package com.ruoyi.accountant.service.impl;

import com.ruoyi.accountant.domain.Account;
import com.ruoyi.accountant.domain.Reason;
import com.ruoyi.accountant.domain.other.*;
import com.ruoyi.accountant.mapper.*;
import com.ruoyi.accountant.service.ReportService;
import com.ruoyi.web.web.form.CashFlowForm;
import com.ruoyi.web.web.form.StatusForm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Transactional
@Service
public class ReportServiceImpl implements ReportService {


    //原reportDao移动到了mapper文件，此处已改
    @Autowired
    private ReportDao reportDao;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private ReasonMapper reasonMapper;




    @Autowired
    private AccountMapper accountMapper;
    @Override
    public List<ProfitLossReportRow> findMonthMoneyCountByTypeAndReason(String type, Long ofReason) {
//        List<ProfitLossReport> monthMoneyCountByTypeAndReason = reportDao.findMonthMoneyCountByTypeAndReason(type, ofReason);
        List<Reason> reasons = reasonMapper.findAllByParent(ofReason);
//        List<ProfitLossReport> profitLossReports = new ArrayList<>();
        List<List<ProfitLossReport>> monthMoneyCountByTypeAndReason=new ArrayList<>();

        for (Reason reason : reasons) {
            List<ProfitLossReport> profitLossReports= reportMapper.findByTypeAndReason(type,reason.getRid());
            System.out.println(profitLossReports);
            monthMoneyCountByTypeAndReason.add(profitLossReports);
        }
        System.out.println("sssssssssssss");
        System.out.println(monthMoneyCountByTypeAndReason);

        // 补足没有记录的月数
        for (List<ProfitLossReport> profitLossReports : monthMoneyCountByTypeAndReason) {
            if(profitLossReports.size() == 0) {
                continue;
            } else {
                for(int x = 1; x<=12; x++) {
                    boolean t = false; // 不存在
                    for (ProfitLossReport profitLossReport : profitLossReports) {
                        if(profitLossReport.getMonth() == x) {
                            t = true;
                        }
                    }
                    if(!t) {
                        ProfitLossReport profitLossReport = new ProfitLossReport(x, new BigDecimal(0), profitLossReports.get(0).getRname(), new BigDecimal(0));
                        profitLossReports.add(profitLossReport);
                    }
                }
            }
        }
        List<List<ProfitLossReport>> list = new ArrayList<List<ProfitLossReport>>();
        for (List<ProfitLossReport> profitLossReports : monthMoneyCountByTypeAndReason) {
            if(profitLossReports.size() > 0) {
                list.add(profitLossReports);
            }
        }

        // 按月排序, 并且计算原因具体综合
        List<ProfitLossReportRow> rows = new ArrayList<ProfitLossReportRow>();
        for (List<ProfitLossReport> profitLossReports : list) {
            Collections.sort(profitLossReports);

            // 计算总金额
            BigDecimal count = new BigDecimal(0);
            for (ProfitLossReport profitLossReport : profitLossReports) {
                count = count.add(profitLossReport.getMoney());
            }

            rows.add(new ProfitLossReportRow(profitLossReports, count));
        }

        //计算父原因总额
        for(int j = 1; j <= 12; j++) {
            BigDecimal monthCount = new BigDecimal(0);
            for (ProfitLossReportRow row : rows) {
                monthCount = monthCount.add(row.getDataByMonth(j));
            }

            ProfitLossReport profitLossReport = new ProfitLossReport();
            profitLossReport.setMonth(j);
            profitLossReport.setRname("");
            profitLossReport.setMoney(monthCount);

            for (ProfitLossReportRow row : rows) {
                row.getParentData().add(profitLossReport);
            }
        }

        return rows;
    }

    @Override
    public Cashflow findCashFlow(CashFlowForm form) {
        Cashflow cashflow = new Cashflow();

        //1.查询各个现金账户在表单end时间的余额
        List<CashFlowItem> income = reportMapper.findCashFlowByType("收入", form.getStart(), form.getEnd(),form.getOfCompany());
        cashflow.setIncomeList(income);
//        System.out.println("------------------------------");
//        System.out.println(income);
//        for(int x = 0; x < income.size(); x++) {
//            CashFlowItem next = income.get(x);
//            CashFlowItem cashFlowItem = new CashFlowItem();
//            cashFlowItem.setAccountName((String) next[3]);
//            cashflow.addIncome(cashFlowItem);
//
//
//            CashFlowItem sub = new CashFlowItem((BigDecimal) next[0], (String) next[1], (String) next[3]);
//            cashFlowItem.add(sub);
//
//            for(int y = x + 1; y < income.size(); y++) {
//                Object[] objects1 = income.get(y);
//                if(objects1[2] != next[2]) { // 如果不是一个账户
//                    break;
//                } else {
//                    sub = new CashFlowItem((BigDecimal) objects1[0], (String) objects1[1], (String) objects1[3]);
//                    cashFlowItem.add(sub);
//                    x++;
//                }
//            }
//        }

        List<CashFlowItem> pay = reportMapper.findCashFlowByType("支出", form.getStart(), form.getEnd(),form.getOfCompany());
        cashflow.setPayList(pay);
//        for(int x = 0; x < pay.size(); x++) {
//            Object[] objects = pay.get(x);
//            CashFlowItem cashFlowItem = new CashFlowItem();
//            cashFlowItem.setAccountName((String) objects[3]);
//            cashflow.addPay(cashFlowItem);
//
//
//            CashFlowItem sub = new CashFlowItem((BigDecimal) objects[0], (String) objects[1], (String) objects[3]);
//            cashFlowItem.add(sub);
//
//            for(int y = x + 1; y < pay.size(); y++) {
//                Object[] next = pay.get(y);
//                if(next[2] != objects[2]) { // 如果不是一个账户
//                    break;
//                } else {
//                    sub = new CashFlowItem((BigDecimal) next[0], (String) next[1], (String) next[3]);
//                    cashFlowItem.add(sub);
//                    x++;
//                }
//            }
//        }
        System.out.println(cashflow);

        return cashflow;
    }

    @Override
    public StatusResult findStatusByReason(StatusForm form) {
        // 查询有待收款哪些原因
        List<Reason> reasonList =  reasonMapper.findByIds("应收款");

        StatusResult statusResult = new StatusResult(); // 财务状况表结果

        // 根据原因查询币种的收入总额
        for (Reason reason : reasonList) {
            List<Object[]> result = reportMapper.findByTypeAndReasonS("应收款", reason.getRid());
            if(result.size() == 0) {
                continue;
            }

            SingleStatusResult singleStatusResult = new SingleStatusResult();
            singleStatusResult.setReasonName(reason.getRname());

            for (Object[] objects : result) {
                SingleStatusResult r = new SingleStatusResult();
                r.setReasonName(reason.getRname());
                r.setMoney((BigDecimal) objects[0]);
                r.setCurrencyName((String) objects[1]);
                singleStatusResult.add(r);
            }

            // 包装币种和结果
            statusResult.addIncome(singleStatusResult);
        }


        // 查询有待收款哪些原因
        List<Reason> reasonList2 =  reasonMapper.findByIds("应付款");
        for (Reason reason : reasonList2) {
            List<Object[]> result = reportMapper.findByTypeAndReasonS("应付款", reason.getRid());
            SingleStatusResult singleStatusResult = new SingleStatusResult();
            singleStatusResult.setReasonName(reason.getRname());

            for (Object[] objects : result) {
                SingleStatusResult r = new SingleStatusResult();
                r.setReasonName(reason.getRname());
                r.setMoney((BigDecimal) objects[0]);
                r.setCurrencyName((String) objects[1]);
                singleStatusResult.add(r);
            }

            // 包装币种和结果
            statusResult.addPay(singleStatusResult);
        }

        // 包装数据返回
        return statusResult;
    }

    @Override
    public StatusResult findStatusByAccount(StatusForm form) {
        // 查询有待收款哪些原因
        List<Account> accountList =  accountMapper.findInaccountByIds();

        StatusResult statusResult = new StatusResult(); // 财务状况表结果

        // 根据原因查询币种的收入总额
        for (Account account : accountList) {
            List<Object[]> result = reportDao.findSumMoneyByInaccount(account.getAid());
            if(result.size() == 0) {
                continue;
            }

            SingleStatusResult singleStatusResult = new SingleStatusResult();
            singleStatusResult.setReasonName(account.getAname());

            for (Object[] objects : result) {
                SingleStatusResult r = new SingleStatusResult();
                r.setReasonName(account.getAname());
                r.setMoney((BigDecimal) objects[0]);
                r.setCurrencyName((String) objects[1]);
                singleStatusResult.add(r);
            }

            // 包装币种和结果
            statusResult.addIncome(singleStatusResult);
        }


        // 查询有待收款哪些原因
        List<Account> reasonList2 =  accountMapper.findOutaccountByIds();
        for (Account account : reasonList2) {
            List<Object[]> result = reportDao.findSumMoneyByOutaccount(account.getAid());
            SingleStatusResult singleStatusResult = new SingleStatusResult();
            singleStatusResult.setReasonName(account.getAname());

            for (Object[] objects : result) {
                SingleStatusResult r = new SingleStatusResult();
                r.setReasonName(account.getAname());
                r.setMoney((BigDecimal) objects[0]);
                r.setCurrencyName((String) objects[1]);
                singleStatusResult.add(r);
            }

            // 包装币种和结果
            statusResult.addPay(singleStatusResult);
        }

        // 包装数据返回
        return statusResult;
    }
}
